import re

from bs4 import BeautifulSoup
from fastapi import APIRouter
from re_common.baselibrary.tools.myparsel import MParsel
from re_common.baselibrary.utils.basedict import BaseDicts
from re_common.baselibrary.utils.core.mlamada import bools_string

from apps.core.callback import default_call_back
from apps.core.global_model import ParseHtmlModel
from apps.core.m_route import ContextIncludedRoute
from apps.core.return_info import InputInfoModel, ReturnInfo

router = APIRouter(route_class=ContextIncludedRoute)


@router.post("/step1/parse_home")
async def parse_article(input: InputInfoModel[ParseHtmlModel]):
    """
    解析首页 得到分类
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    html = input.data.html

    def bs4_change_tag(html):
        soup = BeautifulSoup(html, features="lxml")
        div_tag = soup.find(style="margin:10px 5px;border:1px solid #cedff2;background-color:#f5faff;padding:5px")
        div2_tag = div_tag.find(style="padding:0 5px;")
        b_tag = div2_tag.p.b
        div2_tag.p.b.extract()
        div2_tag.p.font.unwrap()
        font_tag = soup.new_tag("font")
        font_tag['size'] = "-1"
        div2_tag.p.wrap(font_tag)
        div2_tag.font.p.unwrap()
        p_tag = soup.new_tag("p")
        div2_tag.font.wrap(p_tag)
        div2_tag.p.font.insert_before(b_tag)
        return soup.prettify()

    html = bs4_change_tag(html)

    css_dicts = {
        'parent': 'div[id="bodyContent"] > div[style^="margin:10px"]',
        'children': {
            'one_class': 'div[class="headline-2"] > *::text',
            'other': 'dl > dt > a::text',
            'other_url': 'dl > dt > a::attr(href)',
            'parent': 'p',
            'children': {
                "two_class": 'p > b > a::text',
                "two_class_url": 'p > b > a::attr(href)',
                "parent": 'p > font > b,p > font > b ~ a,p > font > b > a',
                "symbol": 'p *::text',
                'children': {
                    "three_class": 'b > a::text',
                    "three_class_url": 'b > a::attr(href)',
                    "four_class": 'a::text',
                    "four_class_url": 'a::attr(href)',
                }
            }
        }
    }
    mc = MParsel(html=html)
    new_dict = mc.css_parsel(sel=mc.sel, css_selector=css_dicts)
    BaseDicts.get_recursive_dict(new_dict, None, default_call_back)
    lists = []

    def one_dicts(category_name, category_url, leavels, parent_name, full_parent_name):
        """
        存入数据库的一条完整的数据的结构
        """
        new_dict = {}
        new_dict["category_name"] = category_name
        new_dict["url"] = category_url
        new_dict["leavels"] = leavels
        new_dict["parent_name"] = parent_name
        new_dict["full_parent_name"] = full_parent_name
        lists.append(new_dict)

    for item in new_dict["children"]:
        one_class = item["one_class"]  # 第一层级分类,无url
        other = item["other"]
        other_url = item["other_url"]
        for name, url in zip(other.split(";"), other_url.split(";")):
            one_dicts(name, url, 3, "其他", one_class + ";其他")
        for item_two in item["children"]:
            two_class = item_two["two_class"]
            two_class_url = item_two["two_class_url"]
            if two_class.find(";") > -1:
                for name, url in zip(two_class.split(";"), two_class_url.split(";")):
                    one_dicts(name, url, 3, "其他", one_class + ";其他")
                break
            one_dicts(two_class, two_class_url, 2, one_class, one_class)
            temp_dicts = {}
            for temp_item in item_two["children"]:
                three_class = temp_item["three_class"]
                three_class_url = temp_item["three_class_url"]
                four_class = temp_item["four_class"]
                four_class_url = temp_item["four_class_url"]
                if three_class:
                    temp_dicts[three_class] = three_class_url
                if four_class:
                    temp_dicts[four_class] = four_class_url
            parent_name = two_class
            full_parent_name = one_class + ";" + two_class
            befor_name = ""
            leavels = 3
            for item_symbol in item_two["symbol"].split(";"):
                item_symbol = item_symbol.strip()
                if item_symbol in ("］·", "·", "）］·", "）·", "））］·"):
                    item_symbol = item_symbol.replace("·", "").strip()
                item_list = [item_symbol]
                if item_symbol == "）］" or item_symbol == "））］":
                    item_list = list(item_symbol)

                for item_symbol in item_list:
                    if befor_name == "葡萄酒公司" and item_symbol == "］、":
                        continue
                    if item_symbol in ("", "、", one_class, two_class, "其它：", "其他："):
                        continue
                    if item_symbol in ("［", "（", "、（"):
                        parent_name = befor_name
                        full_parent_name = full_parent_name + ";" + befor_name
                        leavels = leavels + 1
                        continue
                    if item_symbol in ("］", "）、", "）", "］、", "））、"):
                        full_list = full_parent_name.split(";")
                        befor_name = full_list.pop()
                        parent_name = full_list[-1]
                        full_parent_name = ";".join(full_list)
                        leavels = leavels - 1
                        continue

                    name = item_symbol
                    url = temp_dicts[name]
                    one_dicts(name, url, leavels, parent_name, full_parent_name)
                    befor_name = name

    return_info.status = bools_string(True)
    return_info.msg_code = 200
    return_info.msg = ""
    return_info.data = {"result": lists}
    return return_info.todict()


@router.post("/step2/parse_class")
async def parse_article(input: InputInfoModel[ParseHtmlModel]):
    """
    解析文章的id
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    html = input.data.html
    css_dicts = {
        'url': 'div[id="bodyContent"] > a::attr(href)',
        'url_text': 'div[id="bodyContent"] > a::text',
        'num': 'div[class="category_des"] > p::text',
        'title': 'h1[class="firstHeading"]::text',
        'class': {
            'parent': 'div[id="bodyContent"] > table > tr > td > h3,div[id="bodyContent"] > table > tr > td > ul,div[id="bodyContent"] > h3,div[id="bodyContent"] > ul',
            'children': {
                "AZ_class": "h3::text",
                "class_name": "ul > li > div > div > a::text",
                "class_url": "ul > li > div > div > a::attr(href)",
            }
        },
        'article': {
            'parent': 'div[class="page_ul"] > table > tr > td > h3,div[class="page_ul"] > table > tr > td > ul,div[class="page_ul"] > h3,div[class="page_ul"] > ul',
            'children': {
                "AZ_class": "h3::text",
                "article_name": "ul > li > a::text",
                "article_url": "ul > li > a::attr(href)",
            }
        }

    }
    mc = MParsel(html=html)
    new_dict = mc.css_parsel(sel=mc.sel, css_selector=css_dicts)
    BaseDicts.get_recursive_dict(new_dict, None, default_call_back)

    num_class = re.findall(r'(\d+)个亚类', new_dict["num"])
    num_article = re.findall(r'(\d+)个条目', new_dict["num"])
    if num_class:
        num_class = int(num_class[0])
    else:
        num_class = 0
    if num_article:
        num_article = int(num_article[0])
    else:
        num_article = 0
    title = new_dict["title"].replace("Category:", "")
    urls = ""
    for url in new_dict["url"].split(";"):
        if url.find("from=") > -1:
            urls = url
    lists = []
    az = ""
    for item in new_dict["article"]["children"]:
        AZ_class = item["AZ_class"]
        AZ_class = AZ_class.replace("续", "")
        if AZ_class != "":
            az = AZ_class
        article_name = item["article_name"]
        article_url = item["article_url"]
        for name, url in zip(article_name.split(";"), article_url.split(";")):
            if name == "":
                continue
            lists.append((name, url, az))

    lists_class = []
    az = ""
    for item in new_dict["class"]["children"]:
        AZ_class = item["AZ_class"]
        AZ_class = AZ_class.replace("续", "")
        if AZ_class != "":
            az = AZ_class
        class_name = item["class_name"]
        class_url = item["class_url"]
        for name, url in zip(class_name.split(";"), class_url.split(";")):
            if name == "":
                continue
            lists_class.append((name, url, az))
    if len(lists) == num_article and len(lists_class) == num_class:
        description = f"正确:亚类:{num_class},文章{num_article}; "
    else:
        description = f"错误:亚类:{num_class},文章{num_article}; 实际亚类:{len(lists_class)},文章{len(lists)}"
    return_info.status = bools_string(True)
    return_info.msg_code = 200
    return_info.msg = ""
    return_info.data = {"title": title,
                        "url": urls,
                        "description": description,
                        "list": lists,
                        "lists_class": lists_class}
    return return_info.todict()
